package cn.ctyun.cloudflow.sdk.util;

import java.nio.charset.StandardCharsets;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.Base64;
import java.util.Date;
import java.util.Objects;


public class Signer {

    public static String getEopAuthorization(String eopDate, String sortQuery, String body, String ak, String sk, String requestId) throws NoSuchAlgorithmException, InvalidKeyException {
        Objects.requireNonNull(eopDate, "eopDate is null");
        Objects.requireNonNull(ak, "eopDate is null");
        Objects.requireNonNull(sk, "eopDate is null");
        Objects.requireNonNull(requestId, "requestId is null");

        Date eopDateObject;
        try {
            eopDateObject = new SimpleDateFormat("yyyyMMdd'T'HHmmss'Z'").parse(eopDate);
        } catch (ParseException e) {
            throw new RuntimeException("eopDate is invalid format");
        }

        body = (body == null ? "" : body);
        sortQuery = (sortQuery == null ? "" : sortQuery);


        String calculateContentHash = Codec.hexSHA256(body);

        String singerDd = new SimpleDateFormat("yyyyMMdd").format(eopDateObject);

        // header的key按照26字母进行排序
        String encHeader = String.format("ctyun-eop-request-id:%s\neop-date:%s\n", requestId, eopDate);

        String sigture = encHeader + "\n" + sortQuery + "\n" + calculateContentHash;
//        System.out.println("sigture:" + sigture);

        byte[] ktime = Codec.HmacSHA256(eopDate.getBytes(), sk.getBytes());
//        System.out.println("ktime:" + HexUtils.bytes2Hex(ktime));

        byte[] kak = Codec.HmacSHA256(ak.getBytes(), ktime);
//        System.out.println("kAk:" + HexUtils.bytes2Hex(kak));

        byte[] kdate = Codec.HmacSHA256(singerDd.getBytes(), kak);
//        System.out.println("kdate:" + HexUtils.bytes2Hex(kdate));

        byte[] sw = Codec.HmacSHA256(sigture.getBytes(StandardCharsets.UTF_8), kdate);
//        System.out.println("sw:" + HexUtils.bytes2Hex(sw));

        String signature = Base64.getEncoder().encodeToString(sw);
//        System.out.println("---Signature:" + signature);

        String eopAuthorization = String.format("%s Headers=ctyun-eop-request-id;eop-date Signature=%s", ak, signature);
//        System.out.println("eopAuthorization:" + eopAuthorization);

        return eopAuthorization;
    }
}
